package com.udata.server.persistence.dao.impl;

import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.google.gson.Gson;
import com.udata.server.persistence.PMF;
import com.udata.server.persistence.dao.CurrencyRateDao;
import com.udata.server.persistence.model.CurrencyRate;

public class CurrencyRateDaoImpl extends CurrencyRateDao {

	private static final String CURRENCY_SOURCE_DAILY = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
	private static final String CURRENCY_SOURCE_LAST90DAYS = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml";

	@Override
	public CurrencyRate saveCurrencyRate(CurrencyRate currencyRate)
			throws Exception {
		if (currencyRate.getId() == null) {
			currencyRate.setId(currencyRate.buildKey());
		}
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			pm.makePersistent(currencyRate);
		} finally {
			pm.close();
		}
		return currencyRate;
	}

	@Override
	public CurrencyRate loadCurrencyRate(String id) throws Exception {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		CurrencyRate currencyRate = null;
		try {
			currencyRate = pm.getObjectById(CurrencyRate.class, id);
		} finally {
			pm.close();
		}
		return currencyRate;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<CurrencyRate> searchCurrencyRate(String query) throws Exception {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<CurrencyRate> results = null;
		Query q = pm.newQuery(query);
		try {
			results = (List<CurrencyRate>) q.execute();
		} finally {
			pm.close();
		}
		return results;

	}

	@Override
	public List<String> getCountryList() {
		String[] countryArray = new String[] { "CNY","HKD","CAD","GBP","USD","JPY"};
		List<String> countryList = Arrays.asList(countryArray);
		return countryList;
	}

	@SuppressWarnings("unchecked")
	@Override
	public String getJson(String from, List<String> to, String startDate,
			String endDate) throws Exception {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<CurrencyRate> results = null;

		String filter = "";
		if (startDate != null) {
			filter += " date >= " + startDate;
		}

		if (endDate != null) {
			if (filter.length() > 0) {
				filter += " && ";
			}
			filter += " date <= " + endDate;
		}
		if (filter.length() > 0) {
			filter += " && ";
		}
		filter += ":p.contains (to)";
		System.out.println("Filter:" + filter);

		Query q = pm.newQuery(CurrencyRate.class, filter);
		try {
			results = (List<CurrencyRate>) q.execute(to);
		} finally {
			pm.close();
		}
		Gson gson = new Gson();
		String json = gson.toJson(results);
		return json;

	}

	@Override
	public void deleteCurrency() {
		PersistenceManager pm = PMF.get().getPersistenceManager();

		Query q = pm.newQuery(CurrencyRate.class);

		try {
			List<CurrencyRate> results = (List<CurrencyRate>) q.execute();
			for (CurrencyRate cr : results) {
				pm.deletePersistent(cr);
			}
		} finally {
			pm.close();
		}

	}

	@Override
	public List<CurrencyRate> parseCurrencySource() throws Exception {
		List<CurrencyRate> result = new ArrayList<CurrencyRate>();
		URL url = new URL(CURRENCY_SOURCE_DAILY);
		URLConnection conn = url.openConnection();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		Calendar c = Calendar.getInstance();
		String today = sdf.format(c.getTime());

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(conn.getInputStream());
		NodeList nodeList = doc.getElementsByTagName("Cube");
		CurrencyRate cr = null;
		for (int i = 0; i < nodeList.getLength(); ++i) {
			Element currencyElement = (Element) nodeList.item(i);
			String currency = currencyElement.getAttribute("currency");
			if (currency != null && currency.length() > 0) {
				cr = new CurrencyRate();
				cr.setFrom("EUR");
				cr.setTo(currency);
				cr.setRate(Double.valueOf(currencyElement.getAttribute("rate")));
				cr.setDate(Integer.valueOf(today));
				this.saveCurrencyRate(cr);
				result.add(cr);
			}

		}
		return result;
	}
}
